#ifndef __VIMOC_MOCK_MANAGER__
#define __VIMOC_MOCK_MANAGER__

#include "mock_manager_state.hpp"
#include "object.hpp"
#include "exception_thrower.hpp"
#include "not_implemented_exception.hpp"
#include "bad_object_cast.hpp"
#include <string>

using std::string;

namespace vimock {

template<typename ValueType>
ValueType get_default_value() {
	return ValueType();
}

class mock_manager {
public:
	mock_manager();
	template <typename ValueType>
	ValueType invoked(invocation inv) const {
		try {
			object value_to_return(state->invoked(inv));
			return value_to_return.to<ValueType>();
		}
		catch (const bad_object_cast &) {
			return get_default_value<ValueType>();
		}
	}
	void replay();
	void verify();
	template <typename ValueType>
	class expect_options {
	public:
		expect_options(mock_manager_state state) :
			state(state) {
		}
		void ret(ValueType value_to_return) {
			state->record_value_to_return(value_to_return);
		}
		void trw(exception_thrower ex_to_throw) {
			state->record_exception_to_throw(ex_to_throw);
		}
	private:
		mock_manager_state state;
	};
	template <typename ValueType>
	expect_options<ValueType> expect(ValueType ignore) {
		return expect_options<ValueType>(state);
	}
private:
	mock_manager_state state;
};
}

#endif //__VIMOC_MOCK_MANAGER__ 
